﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum WeatherType
{
	Sunny = 0,
	Rainy = 1,
}
public class Weather
{
	public WeatherType type;
	public List<GameObject> WeatherEffects = new List<GameObject> { };
	public bool WithThunder = false;
	public Weather(WeatherType weatherType, List<GameObject> effects = null)
	{
		type = weatherType;
		if (effects != null)
			foreach (var effect in effects)
			{
				WeatherEffects.Add(effect);
			}
	}
	//public AudioClip[] Audios;
}
public class WeatherController : MonoBehaviour
{
	// Start is called before the first frame update
	[Header("Controller")]
	[SerializeField]
	private WeatherType _current;
	[Tooltip("How many seconds for every Weather reselection")]
	public int SwitchWeatherWait = 10;
	[Range(0, 100)]
	[Tooltip("The probability of sunnyday is 100-this value")]
	public float ProbabilityOfRainyDay = 30f;
	[Range(0, 100)]
	public float ProbabilityOfThunderRainDay = 30f;
	[Header("Rainy Day Controlling Panel")]
	public GameObject RainFX;
	public GameObject FogFX;
	public Transform RainAreaGeneratingPosition;
	[Header("Flashing Controlling Panel")]
	public GameObject ThunderFlashing;
	public float FlashingTime = 0.05f;
	#region WeatherControllingParameters
	private Weather _Sunny, _Rainy;
	private GameObject RainyArea_instance;
	private WeatherType _last;
	[SerializeField]
	private bool isThundering = false;
	#endregion
	// Update is called once per frame
	private void Awake()
	{//instantiate two effect type
		_Sunny = new Weather(WeatherType.Sunny);
		StartCoroutine(WeatherSelect());
	}
	private void Update()
	{
		if (_current == WeatherType.Sunny && _last != _current)//if the current weather is sunny and changed since last frame
		{//stop the last effect
			EnableWeather(WeatherType.Sunny);
		}
		else if (_current == WeatherType.Rainy && _last != _current)
		{
			EnableWeather(WeatherType.Rainy);
		}
	}
	private void EnableWeather(WeatherType weather)
	{
		switch (weather)
		{
			case WeatherType.Sunny:
				{
					_last = weather;
					if (_Rainy != null)
					{
						_Rainy.WeatherEffects[0].GetComponent<ParticleSystem>().Stop();
						if (isThundering)
						{
							StopCoroutine(SimulateThunder());
							isThundering = false;
						}
						_Rainy = null;
						StartCoroutine(RainDipOut(RainyArea_instance));
					}
					break;
				}
			case WeatherType.Rainy:
				{
					_last = weather;
					RainyArea_instance = Instantiate(RainFX, RainAreaGeneratingPosition);
					_Rainy = new Weather(WeatherType.Rainy, new List<GameObject> { RainyArea_instance });
					_Rainy.WithThunder = (Random.Range(0, 100) < ProbabilityOfThunderRainDay ? true : false);
					if (_Rainy.WithThunder == true)
					{
						isThundering = true;
						StartCoroutine(SimulateThunder());
					}
					break;
				}
		}
	}
	private WeatherType SelectRandomWeather()
	{
		return (WeatherType)(Random.Range(0, 100) < ProbabilityOfRainyDay ? 1 : 0);
	}
	IEnumerator LightFlashing(float FlashingTime, GameObject Light)
	{
		Light.SetActive(true);
		yield return new WaitForSeconds(FlashingTime);
		Light.SetActive(false);
	}
	IEnumerator SimulateThunder()
	{
		while (true)
		{
			if (Random.Range(0, 10) > 5)
			{
				StartCoroutine(LightFlashing(FlashingTime, ThunderFlashing));
				yield return new WaitForSeconds(1f);
				StartCoroutine(LightFlashing(FlashingTime, ThunderFlashing));
			}
			else
			{
				StartCoroutine(LightFlashing(FlashingTime, ThunderFlashing));
			}
			yield return new WaitForSeconds(Random.value % 6 + 3);
			if (!isThundering) break;
		}
	}
	IEnumerator WeatherSelect()
	{
		while (true)
		{
			yield return new WaitForSeconds(SwitchWeatherWait);
			_current = SelectRandomWeather();
		}
	}
	IEnumerator RainDipOut(GameObject _instance)
	{
		yield return new WaitForSeconds(2f);
		Destroy(_instance);
	}
}
